<?php

namespace app\api\service;

use HuaweiCloud\SDK\Live\V1\Model\DeleteDomainMappingRequest;
use HuaweiCloud\SDK\Live\V1\Model\DeleteDomainRequest;
use HuaweiCloud\SDK\Live\V1\Model\ListLiveStreamsOnlineRequest;
use HuaweiCloud\SDK\Live\V1\Model\LiveDomainModifyReq;
use HuaweiCloud\SDK\Live\V1\Model\ShowDomainRequest;
use HuaweiCloud\SDK\Cdn\V1\Model\CreateDomainRequest;
use HuaweiCloud\SDK\Core\Auth\BasicCredentials;
use HuaweiCloud\SDK\Core\Http\HttpConfig;
use HuaweiCloud\SDK\Core\Exceptions\ConnectionException;
use HuaweiCloud\SDK\Core\Exceptions\RequestTimeoutException;
use HuaweiCloud\SDK\Core\Exceptions\ServiceResponseException;
use HuaweiCloud\SDK\Live\V1\LiveClient;
use HuaweiCloud\SDK\Live\V1\Model\CreateDomainMappingRequest;
use HuaweiCloud\SDK\Live\V1\Model\DomainMapping;
use HuaweiCloud\SDK\Live\V1\Model\LiveDomainCreateReq;
use HuaweiCloud\SDK\Live\V1\Model\UpdateDomainRequest;
use Obs\ObsClient;
use think\Env;
use think\Exception;

// 华为OBS对象存储
class HuaWeiOBS
{
    protected $ak = "VNMKYZQ8IFYQE5JWZ77U";//华为云帐号Access Key
    protected $sk = "Nwtl3FmJ2k6fPHMOPM9YGRQaOHpV0uH8CbrGW3ZZ";//华为云帐号Secret Access Key
    protected $bucket = "video-source";//对象存储的桶名称
    //直播服务应用区域和各服务的终端节点
    protected $endpoint = 'https://obs.cn-north-4.myhuaweicloud.com';
    protected $client;
    protected $partSize = 5 * 1024 * 1024;//多段上传文件时的分片大小


    public function __construct()
    {
        $ak = $this->ak;
        $sk = $this->sk;
        $endpoint = $this->endpoint;

        //创建ObsClient实例
        $this->client = new ObsClient([
            'key' => $ak,
            'secret' => $sk,
            'endpoint' => $endpoint
        ]);
    }

    /**
     * 上传文件
     * @param $file 文件对象
     */
    public function putObject($file)
    {

        // 获取文件后缀名
        $source_file = $file['tmp_name'];//待上传对象的源文件路径 $source_file="C:\Users\Administrator\AppData\Local\Temp\phpC9D3.tmp"
        //$path = 'user/' . time() . rand(1111,9999) .'.'. pathinfo($file['name'],PATHINFO_EXTENSION); //带目录版本

        $file_name = time() . rand(1111, 9999) . '.' . pathinfo($file['name'], PATHINFO_EXTENSION);
        $path = 'uploads/' . date('Ymd') . '/' . $file_name;

        $object = $this->client;
        $resp = $object->putObject([
            'Bucket' => $this->bucket,//桶名称
            'Key' => $path,//对象名 路径+文件名+文件后缀 如:user/pic123.png
            'SourceFile' => $source_file,  //待上传对象的源文件路径。 localfile为待上传的本地文件路径，需要指定到具体的文件名
            'ACL' => 'public-read' // 设置对象ACL为"公共读"
        ]);
        $res = [
            'code' => 500,
        ];
        if ($resp['HttpStatusCode'] == 200) {
            $res = [
                'code' => 200,
                'path' => '/' . $path, //相对路径
                'url' => Env::get('app.obsurl') . '/' . $path,
                'file_name' => $file_name,
            ];
        }
        return $res;
    }

    //分段上传
    public function subsectionUpload($file){
        $file_name = time() . rand(1111, 9999) . '.' . pathinfo($file['name'], PATHINFO_EXTENSION);
        $path = 'uploads/' . date('Ymd') . '/' . $file_name;
        $source_file = $file['tmp_name'];//待上传对象的源文件路径

        $initiateMultipartUpload = $this->initiateMultipartUpload($path);//初始化

        //执行分段上传
        $this->uploadPart($source_file,$path,$initiateMultipartUpload['UploadId']);

    }

    //初始化分段上传任务
    public function initiateMultipartUpload($path)
    {
        $object = $this->client;
        //初始化分段上传任务
        $resp = $object->initiateMultipartUpload([
            'Bucket' => $this->bucket,//桶名称
            'Key' => $path,//对象名 路径+文件名+文件后缀 如:user/pic123.png
            'ContentType' => 'text/plain',
            'Metadata' => ['property' => 'property-value'],
            'ACL' => 'public-read' // 设置对象ACL为"公共读"
        ]);
//        printf("RequestId:%s\n",$resp['RequestId']);
//        printf("UploadId:%s\n",$resp['UploadId']);
        return $resp->toArray();
    }

    //逐个或并行开始上传段
    public function uploadPart($source_file,$path,$upload_id,$part_number){
        $object = $this->client;
        $resp = $object->uploadPart([
            'Bucket' => $this->bucket,//桶名称
            'Key' => $path,//对象名 路径+文件名+文件后缀 如:user/pic123.png
            // 设置分段号，范围是1~10000
            'PartNumber' => $part_number,
            // 设置Upload ID
            'UploadId' => $upload_id,
            // 设置将要上传的大文件,localfile为上传的本地文件路径，需要指定到具体的文件名
            'SourceFile' => $source_file,
            // 设置分段大小
            'PartSize' => $this->partSize,
            // 设置分段的起始偏移大小
            'Offset' => 0
        ]);

//        printf("RequestId:%s\n",$resp['RequestId']);
//        printf("ETag:%s\n",$resp['ETag']);
        return $resp->toArray();
    }
    //合并段
    public function completeMultipartUpload($upload_id,$parts,$path){
        $object = $this->client;
        $resp = $object->completeMultipartUpload([
            'Bucket' => $this->bucket,//桶名称
            'Key' => $path,//对象名 路径+文件名+文件后缀 如:user/pic123.png
            // 设置Upload ID
            'UploadId' => $upload_id,
            'Parts' => $parts
        ]);

        if ($resp['HttpStatusCode'] == 200){
            $res = [
                'code' => 200,
                'path' => $resp['Key'],
                'url' => Env::get('app.obsurl') . '/' . $resp['Key'],
            ];
        }else{
            $res = [
                'code' => 500,
            ];
        }

        //printf("RequestId:%s\n",$resp['RequestId']);
        return $res;
    }


}
